/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

//import { onUnexpectedError } from 'vs/base/common/errors';
import { ExtensionHostMain } from 'vs/workbench/node/extensionHostMain';
import { IInitData } from 'vs/workbench/api/node/extHost.protocol';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
// import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
// import { Protocol } from 'vs/base/parts/ipc/node/ipc.net';
// import { createConnection } from 'net';
// import Event, { filterEvent } from 'vs/base/common/event';

// interface IRendererConnection {
// 	protocol: IMessagePassingProtocol;
// 	initData: IInitData;
// }

// This calls exit directly in case the initialization is not finished and we need to exit
// Otherwise, if initialization completed we go to extensionHostMain.terminate()
// let onTerminate = function () {
// 	exit();
// };

// function createExtHostProtocol(): Promise<IMessagePassingProtocol> {

// 	const pipeName = process.env.VSCODE_IPC_HOOK_EXTHOST;

// 	return new Promise<IMessagePassingProtocol>((resolve, reject) => {

// 		const socket = createConnection(pipeName, () => {
// 			socket.removeListener('error', reject);
// 			resolve(new Protocol(socket));
// 		});
// 		socket.once('error', reject);

// 	}).then(protocol => {

// 		return new class implements IMessagePassingProtocol {

// 			private _terminating = false;

// 			readonly onMessage: Event<any> = filterEvent(protocol.onMessage, msg => {
// 				if (msg.type !== '__$terminate') {
// 					return true;
// 				}
// 				this._terminating = true;
// 				//onTerminate();
// 				return false;
// 			});

// 			send(msg: any): void {
// 				if (!this._terminating) {
// 					protocol.send(msg);
// 				}
// 			}
// 		};
// 	});
// }

function connectToRenderer(): Promise<IInitData> {
	return new Promise<IInitData>((c, e) => {
		var func = (ev: CustomEvent) => {
			window.removeEventListener("rawData", func);
			const initData = ev.detail as IInitData;

			// Tell the outside that we are initialized
			window.dispatchEvent(new CustomEvent("initialized"));
			//protocol.send('initialized');

			c(initData);
		};
		window.addEventListener("rawData", func);
		// Listen init data message
		// const first = protocol.onMessage(raw => {
		// 	first.dispose();

		// 	const initData = <IInitData>JSON.parse(raw);

		// 	// Print a console message when rejection isn't handled within N seconds. For details:
		// 	// see https://nodejs.org/api/process.html#process_event_unhandledrejection
		// 	// and https://nodejs.org/api/process.html#process_event_rejectionhandled
		// 	const unhandledPromises: Promise<any>[] = [];
		// 	process.on('unhandledRejection', (reason: any, promise: Promise<any>) => {
		// 		unhandledPromises.push(promise);
		// 		setTimeout(() => {
		// 			const idx = unhandledPromises.indexOf(promise);
		// 			if (idx >= 0) {
		// 				unhandledPromises.splice(idx, 1);
		// 				console.warn('rejected promise not handled within 1 second');
		// 				onUnexpectedError(reason);
		// 			}
		// 		}, 1000);
		// 	});
		// 	process.on('rejectionHandled', (promise: Promise<any>) => {
		// 		const idx = unhandledPromises.indexOf(promise);
		// 		if (idx >= 0) {
		// 			unhandledPromises.splice(idx, 1);
		// 		}
		// 	});

		// 	// Print a console message when an exception isn't handled.
		// 	process.on('uncaughtException', function (err: Error) {
		// 		onUnexpectedError(err);
		// 	});

		// 	// Kill oneself if one's parent dies. Much drama.
		// 	setInterval(function () {
		// 		try {
		// 			process.kill(initData.parentPid, 0); // throws an exception if the main process doesn't exist anymore.
		// 		} catch (e) {
		// 			//onTerminate();
		// 		}
		// 	}, 5000);

		// 	// Tell the outside that we are initialized
		// 	window.dispatchEvent(new CustomEvent("initialized"));
		// 	//protocol.send('initialized');

		// 	c({ protocol, initData });
		// });

		window.dispatchEvent(new CustomEvent("ready"));
		// Tell the outside that we are ready to receive messages
		//protocol.send('ready');
	});
}

// patchExecArgv();

export function startup(instantiationService: IInstantiationService) {
	return connectToRenderer().then(data => {
		// setup things
		const extensionHostMain = new ExtensionHostMain(instantiationService, data);
		//onTerminate = () => extensionHostMain.terminate();
		return extensionHostMain.start();
	}).catch(err => console.error(err));
}



// function patchExecArgv() {
// 	// when encountering the prevent-inspect flag we delete this
// 	// and the prior flag
// 	if (process.env.VSCODE_PREVENT_FOREIGN_INSPECT) {
// 		for (let i = 0; i < process.execArgv.length; i++) {
// 			if (process.execArgv[i].match(/--inspect-brk=\d+|--inspect=\d+/)) {
// 				process.execArgv.splice(i, 1);
// 				break;
// 			}
// 		}
// 	}
// }
